package cn.wizzer.app.user.util;

import cn.hutool.crypto.SecureUtil;
import cn.wizzer.app.user.modules.models.dto.XindovndRechargeDTO;
import cn.wizzer.app.user.modules.models.dto.XindovndWithdrawDTO;
import cn.wizzer.framework.util.HttpUtil;
import cn.wizzer.framework.util.JSONUtil;
import cn.wizzer.framework.util.Result;
import com.google.common.base.Charsets;
import org.nutz.log.Log;
import org.nutz.log.Logs;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * 京都泰国
 */
public class XindovndUtil {

    private static final Log log = Logs.get();

    public static String send(String url, Map<String, Object> params) throws IOException {
        String body = HttpUtil.createRequest()
                .setUrl(url)
                .setHeader("Content-Type", "application/x-www-form-urlencoded")
                .setParam(params)
                .send()
                .getBodyAndClose();
        log.info("XindovanUtil.send(url:" + url + ",params:" + JSONUtil.toJSONString(params) + ")->result:" + body);
        return body;
    }

    /**
     * @param amount        金额
     * @param merchant      商户ID
     * @param bankname      代付银行名称
     * @param cardno        代付账户
     * @param cardname      代付账户只有人姓名
     * @param notifyurl     代付成功回调地址
     * @param outtransferno 商户代付订单号
     * @param secret        商户秘钥-用以加密sign
     * @return
     * @throws UnsupportedEncodingException
     */
    public static Map<String, Object> createWithdrawParam(String amount, String merchant, String bankname, String cardno, String cardname, String notifyurl, String outtransferno, String secret) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<>();
        //金额
        params.put("amount", amount);
        //代付银行名称
        params.put("bankname", bankname);
        //商户ID
        params.put("merchant", merchant);
        //代付账户
        params.put("cardno", cardno);
        //代付账户只有人姓名
        params.put("cardname", cardname);
        //代付成功回调地址
        params.put("notifyurl", notifyurl);
        //商户代付订单号
        params.put("outtransferno", outtransferno);
        //备注
        params.put("remark", "");

        String[] keys = params.keySet().toArray(new String[]{});

        StringBuilder stringBuilder = new StringBuilder();
        Arrays.sort(keys);
        for (String key : keys) {
            String val = String.valueOf(params.get(key) == null ? "" : params.get(key));
            stringBuilder.append("&").append(key).append("=").append(URLEncoder.encode(val, Charsets.UTF_8.toString()).toLowerCase());
        }
        //排序后的参数
        String encodeParams = stringBuilder.deleteCharAt(0).toString();
        //拼接商户secret
        String strToHash = encodeParams + "&secret=" + secret;
        //sign
        String hashResult = SecureUtil.md5(strToHash);
        params.put("sign", hashResult);
        return params;
    }

    /**
     * 安全验证
     *
     * @param xin
     * @param secret
     * @return
     */
    public static boolean verifyWithdrawNotify(XindovndWithdrawDTO xin, String secret) throws UnsupportedEncodingException {
        Map<String, String> params = Result.createMap("transferno", xin.getTransferno(),
                "outtransferno", xin.getOuttransferno(),
                "tradeamount", xin.getTradeamount(),
                "transferamount", xin.getTransferamount(),
                "endtime", xin.getEndtime(),
                "remark", xin.getRemark(),
                "status", xin.getStatus());
        String[] keys = params.keySet().toArray(new String[]{});
        Arrays.sort(keys);

        StringBuilder sb = new StringBuilder();
        Arrays.sort(keys);
        for (String key : keys) {
            String val = params.get(key);
            sb.append("&").append(key).append("=").append(URLEncoder.encode(val, Charsets.UTF_8.displayName()).toLowerCase());
        }
        //拼接商户secret
        String strToHash = sb.deleteCharAt(0).toString() + "&secret=" + secret;
        //sign
        String hashResult = SecureUtil.md5(strToHash);
        return hashResult.equals(xin.getSign());
    }

    public static Map<String, Object> createPayParam(String amount, String merchant, String paytype, String notifyurl, String outtradeno, String secret) throws UnsupportedEncodingException {
        Map<String, Object> params = new HashMap<>();
        //金额
        params.put("amount", amount + ".00");
        //商户ID
        params.put("merchant", merchant);
        //代付方式-联系客服看看
        params.put("paytype", paytype);
        //商户订单号
        params.put("outtradeno", outtradeno);
        //无用备注
        params.put("remark", "");
        //代付成功回调地址
        params.put("notifyurl", notifyurl);
        //页面回调地址
        params.put("returnurl", "http://");
        //付款人姓名
        params.put("payername", "");
        //定死格式
        params.put("returndataformat", "serverjson");

        String[] keys = params.keySet().toArray(new String[]{});

        StringBuilder stringBuilder = new StringBuilder();
        Arrays.sort(keys);
        for (String key : keys) {
            String val = String.valueOf(params.get(key));
            stringBuilder.append("&").append(key).append("=").append(URLEncoder.encode(val, Charsets.UTF_8.displayName()).toLowerCase());
        }
        //排序后的参数
        String encodeParams = stringBuilder.deleteCharAt(0).toString();
        //拼接商户secret
        String strToHash = encodeParams + "&secret=" + secret;
        //sign
        String hashResult = SecureUtil.md5(strToHash);
        params.put("sign", hashResult);
        return params;
    }

    public static boolean verifyRechargeNotify(XindovndRechargeDTO xin, String secret) throws UnsupportedEncodingException {
        Map<String, String> params = Result.createMap("tradeno", xin.getTradeno(),
                "outtradeno", xin.getOuttradeno(),
                "amount", xin.getAmount(),
                "ramount", xin.getRamount(),
//                "oamount", xin.getRamount(),
                "endtime", xin.getEndtime(),
                "remark", xin.getRemark(),
                "status", xin.getStatus());
        String[] keys = params.keySet().toArray(new String[]{});
        Arrays.sort(keys);

        StringBuilder sb = new StringBuilder();
        Arrays.sort(keys);
        for (String key : keys) {
            String val = params.get(key);
            sb.append("&").append(key).append("=").append(val == null ? "" : URLEncoder.encode(val, Charsets.ISO_8859_1.displayName()).toLowerCase());
        }
        //拼接商户secret
        String strToHash = sb.deleteCharAt(0).toString() + "&secret=" + secret;
        //sign
        String hashResult = SecureUtil.md5(strToHash);
        return hashResult.equals(xin.getSign());
    }
}
